package framework.states;

import java.util.Timer;
import java.util.TimerTask;

import org.newdawn.slick.AngelCodeFont;
import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Point;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;

import character.*;
import framework.BasicActionGetter;
import framework.BasicActionGetterInstance;
import framework.BasicFighter;
import framework.C;
import framework.Controls;
import framework.FontManager;
import framework.Util;
import framework.ia.Brain;

public class FighterSelect extends BackableState {

	protected BasicFighter[][] fighters1 = {
			{ new Nartan(), new Arfok(), new Snowman(), new Yefi() }
	};

	protected BasicFighter[][] fighters2 = {
			{ new Nartan(), new Arfok(), new Snowman(), new Yefi() }
	};

	protected int cursorY1, cursorY2, cursorX1, cursorX2;

	protected Point cursor1, cursor2;

	protected boolean selected1, selected2;

	protected boolean back;

	protected Brain useIa1;

	protected Brain useIa2;

	protected BasicActionGetter caller;

	protected AngelCodeFont font;
	
	protected AngelCodeFont fontCharacter;
	
	protected Image bg;
	
	protected boolean transitioning;

	public FighterSelect() {
		cursor1 = new Point(0, 0);
		cursor2 = new Point(0, 0);
		selected1 = selected2 = false;
		caller = BasicActionGetterInstance.getInstance();
		useIa1 = null;
		useIa2 = null;
		transitioning = false;
		try {
			font = FontManager.getBig();
			fontCharacter = FontManager.getMenuHover();
			bg = new Image(C.ASSETS_FOLDER + "background.jpg");
		} catch (SlickException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void enter(GameContainer gc, StateBasedGame game)
			throws SlickException {
		selected1 = selected2 = false;
		setIsBack(false);
		cursor1 = new Point(0, 0);
		cursor2 = new Point(0, 0);
		transitioning = false;
		for (int i=0; i < fighters1.length; i++) {
			for (int j=0; j < fighters1[i].length; j++) {
				fighters1[i][j].setScale(Util.getScale(gc));
				fighters2[i][j].setScale(Util.getScale(gc));
			}
		}
	}

	@Override
	public void render(GameContainer gc, StateBasedGame sg, Graphics g)
			throws SlickException {
		Animation a1, a2;
		Image img = null;
		a1 = a2 = null;
		int startX = 0;
		int miniSize = gc.getHeight() / 8;
		int startY = gc.getHeight() / 3;
		String f1Name = "";
		String f2Name = "";
		String select;
		BasicFighter f1, f2;
		f1 = f2 = null;
		bg.draw(0, 0, gc.getWidth(), gc.getHeight());
		g.setFont(font);
		g.setLineWidth(6);
		g.setColor(Color.white);
		
		select = transitioning ? C.S.READY : C.S.SELECT;
		
		g.drawString(select, gc.getWidth() / 2 - font.getWidth(select) / 2, gc.getHeight() / 5 - font.getHeight(C.S.SELECT));
		
		for(int col=0; col < fighters1.length; col++) { 
			for(int row=0; row < fighters1[col].length ; row++) {
				img = fighters1[col][row].getAnimations().getMini(true);
				if (row == cursor1.getX() && col == cursor1.getY()) {
					f1 = fighters1[col][row];
					f1Name = f1.getFighterName();
					a1 = selected1 ? f1.getAnimations().getSelectAnimation(true) : 
						             f1.getAnimations().getIdleAnimation(true);
				}
				if(row == cursor2.getX() && col == cursor2.getY()) {
					f2 = fighters1[col][row];
					f2Name = f2.getFighterName();
					
					a2 = selected2 ? f2.getAnimations().getSelectAnimation(false) :
						             f2.getAnimations().getIdleAnimation(false);
				} 
				startX = gc.getWidth() / 2 - miniSize * fighters1[0].length / 2;

				g.setColor(Color.white);
				g.fillRect(startX + miniSize * row, startY + col * miniSize, miniSize, miniSize);
				g.setColor(Color.black);
				g.setLineWidth(Util.getScale(gc) * 5);
				g.drawRect(startX + miniSize * row, startY + col * miniSize, miniSize, miniSize);
				img.draw(startX + miniSize * row, startY + col * miniSize, miniSize, miniSize);
			}
		}
		
		g.setColor(Color.white);
		
		g.drawString("VS", gc.getWidth() / 2 - font.getWidth("VS") / 2, gc.getHeight() / 1.3f - font.getHeight("VS") / 2);
		g.setFont(fontCharacter);
		g.drawString(f1Name, gc.getWidth() * 0.25f - fontCharacter.getWidth(f1Name) / 2, gc.getHeight() / 1.8f - fontCharacter.getHeight(f1Name) / 2);
		g.drawString(f2Name, gc.getWidth() - gc.getWidth() * 0.25f - fontCharacter.getWidth(f2Name) / 2, gc.getHeight() / 1.8f - fontCharacter.getHeight(f2Name) / 2);
        a1.draw(gc.getWidth() * 0.25f - f1.getWidth() / 2, gc.getHeight() - f1.getHeight() * 1.5f, f1.getWidth(), f1.getHeight());
        a2.draw(gc.getWidth() - gc.getWidth() * 0.25f - f2.getWidth() / 2, gc.getHeight() - f2.getHeight() * 1.5f, f2.getWidth(), f2.getHeight());

		g.setColor(selected2 ? Color.gray : new Color(255, 0, 0, 255));
		g.drawRect(startX + miniSize * cursor2.getX(), startY + cursor2.getY() * miniSize, miniSize, miniSize);
		g.setFont(C.Font.REGULAR_FONT);
		g.drawString("J2", startX + miniSize * cursor2.getX(), startY + cursor2.getY() * miniSize - C.Font.REGULAR_FONT.getHeight("J1"));
		g.setColor(selected1 ? Color.gray : new Color(100, 100, 255, 255));
		g.drawRect(startX + miniSize * cursor1.getX(), startY + cursor1.getY() * miniSize, miniSize, miniSize);
		g.drawString("J1", startX + miniSize * cursor1.getX() + miniSize - C.Font.REGULAR_FONT.getWidth("J2"), startY + cursor1.getY() * miniSize - C.Font.REGULAR_FONT.getHeight("J2"));
	}

	@Override
	public void update(GameContainer gc, StateBasedGame g, int delta)
			throws SlickException {
		super.update(gc, g, delta);
		if (selected1 && selected2 && !transitioning) {
			((Fight) g.getState(1)).setIa1(useIa1);
			((Fight) g.getState(1)).setIa2(useIa2);
			((Fight) g.getState(1)).setFighter1(fighters1[(int) cursor1.getY()][(int) cursor1.getX()]);
			((Fight) g.getState(1)).setFighter2(fighters2[(int) cursor2.getY()][(int) cursor2.getX()]);
			final StateBasedGame game = g;
			TimerTask task = new TimerTask() {
				@Override
				public void run() {
					game.enterState(1, new FadeOutTransition(), new FadeInTransition());
				}
			};
			Timer t = new Timer();
			t.schedule(task, 1500);
			transitioning = true;
		}
	}
	
	@Override
	public void controllerUpPressed(int controller) {
		Controls c = this.caller.getAction(controller, "up");
		performAction(c);
	}

	@Override
	public void controllerLeftPressed(int controller) {
		Controls c = this.caller.getAction(controller, "left");
		performAction(c);
	}

	@Override
	public void controllerRightPressed(int controller) {
		Controls c = this.caller.getAction(controller, "right");
		performAction(c);
	}

	@Override
	public void controllerButtonPressed(int controller, int button) {
		Controls c = this.caller.getAction(controller, "" + button);
		System.out.println(c);
		performAction(c);
	}

	public void performAction(Controls c) {
		if (c == null) {
			return;
		}
		switch(c) {
		case RIGHT_P1 : moveRight(cursor1);
		break;
		case RIGHT_P2 : moveRight(cursor2);
		break;
		case LEFT_P1 : moveLeft(cursor1);
		break;
		case LEFT_P2 : moveLeft(cursor2);
		break;
		case START_P2 : case A_P2 : selected2 = true;
		break;
		case START_P1 : case A_P1 : selected1 = true;
		break;
		case B_P2 : selected2 = false || transitioning;
		break;
		case B_P1 : selected1 = false || transitioning;
		break;
		default :
			break;
		}
	}

	@Override
	public void keyPressed(int key, char c) {
		super.keyPressed(key, c);
		String input = "" + c;
		if (key == Input.KEY_UP)	{
			input = "up";
		} else if (key == Input.KEY_LEFT)	{
			input = "left";
		} else if (key == Input.KEY_RIGHT)	{
			input = "right";
		}
		Controls cont = this.caller.getAction(-1, input);
		performAction(cont);
	}

	public void moveLeft(Point cursor) {
		if (cursor == cursor1 && selected1 || cursor == cursor2 && selected2) {
			return;
		}

		if(cursor.getX() - 1 < 0) {
			if (cursor.getY() - 1 >= 0) {
				cursor.setY(cursor.getY() - 1);
				cursor.setX(fighters1[(int) cursor.getY()].length - 1);
			} else {
				cursor.setY(fighters1.length - 1);
				cursor.setX(fighters1[0].length - 1);
			}
		} else {
			cursor.setX(cursor.getX() - 1);
		}
		System.out.println("x" + cursor.getX() + "y" + cursor.getY());
	}

	public void moveRight(Point cursor) {
		if (cursor == cursor1 && selected1 || cursor == cursor2 && selected2) {
			return;
		}

		if(cursor.getX() + 1 >= fighters1[(int) cursor.getY()].length) {
			if (cursor.getY() + 1 < fighters1.length) {
				cursor.setY(cursor.getY() + 1);
				cursor.setX(0);
			} else {
				cursor.setY(0);
				cursor.setX(0);
			}
		} else {
			cursor.setX(cursor.getX() + 1);
		}
		System.out.println("x" + cursor.getX() + "y" + cursor.getY());
	}

	@Override
	public int getID() {
		return 7;
	}
}
